package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.CommonConstants;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioProperties;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mappers.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-16
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Override
    public ResponseResult courseList(PageRequest request, CourseDto dto) {
        //查询条件
        LambdaQueryWrapper<CourseBase> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(dto.getCourseName())) {
            wrapper.like(CourseBase::getName,"%"+dto.getCourseName()+"%");
        }
        if (!StringUtils.isEmpty(dto.getTeachmode())) {
            wrapper.like(CourseBase::getTeachmode,dto.getTeachmode());
        }
        if (!StringUtils.isEmpty(dto.getAuditStatus())) {
            wrapper.like(CourseBase::getAuditStatus,dto.getAuditStatus());
        }
        wrapper.eq(CourseBase::getStatus,1);//只查询未删除的

        //设置机构id
//        wrapper.eq(CourseBase::getCompanyId, AuthInfoHolder.getCompanyId());
        //获取分页参数
        //当前页
        Integer pageNo = request.getPageNo();
        //每页条数
        Integer pageSize = request.getPageSize();

        Page<CourseBase> page=new Page<>(pageNo,pageSize);
        //调用方法分页查询
        IPage<CourseBase> iPage=this.page(page,wrapper);
        //构造返回
        return PageResponseResult.okResult(iPage.getTotal(),page.getRecords());
    }
    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioProperties properties;


    @Override
    public ResponseResult upload(MultipartFile uploadFile) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException {
        //1、指定文件
        InputStream stream = uploadFile.getInputStream();
        //2、指定文件上传的位置和文件名称   /images/2022/07/17/uuid +filename
        String filepath = "/images/"+new SimpleDateFormat("yyyy/MM/dd/")
                .format(new Date()) +
                UUID.randomUUID().toString()+uploadFile.getOriginalFilename();
        //3、构造PutObjectArgs参数，并发送请求
        PutObjectArgs objectArgs = PutObjectArgs.builder()
                .contentType("image/jpg") //文件类型
                .stream(stream, stream.available(), -1) //文件流
                .bucket(properties.getBucket()) //存储空间
                .object(filepath) //文件
                .build();
        minioClient.putObject(objectArgs);
        //5、拼接访问地址
        String urlPath = properties.getDomain() +"/" + properties.getBucket() + filepath;

        return ResponseResult.okResult(urlPath);
    }

    @Autowired
    TeachplanService teachplanService;

    @Override
    @Transactional
    public ResponseResult saveCourseBase(CourseBaseDto dto) {
        //验证数据格式
        if (dto==null) {
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //将传入的请求参数dto
        CourseBase courseBase = BeanHelper.copyProperties(dto, CourseBase.class);
        //设置字段
        courseBase.setCompanyName(AuthInfoHolder.getAuthInfo().getCompanyName());
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);//课程审核状态
        courseBase.setStatus(CommonConstants.USING_FLAG);
        courseBase.setCreateDate(new Date());//添加日期
        courseBase.setPlanNum(0);//默认章节

        //保存
        boolean save = this.save(courseBase);
        if (!save){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //初始化一个工程
        Teachplan teachplan = new Teachplan();
        teachplan.setPname(courseBase.getName());
        teachplan.setParentid(0l);
        teachplan.setGrade(CourseConstants.FIRST_LEVEL);
        teachplan.setCourseId(courseBase.getId()); //当前课程计划所属的课程id
        teachplan.setStatus(CommonConstants.USING_FLAG);
        teachplan.setCreateDate(new Date());
        teachplanService.save(teachplan);
        //构造返回
        Map map=new HashMap();
        map.put("courseBaseId",courseBase.getId());
        return ResponseResult.okResult(map);
    }

    @Override
    public ResponseResult updateCourseBase(CourseBaseDto dto) {
        //验证数据格式
        if (dto==null) {
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        CourseBase courseBase = this.getById(dto.getId());
        if (courseBase==null) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //判断课程状态,是否可以修改课程
        String auditStatus = courseBase.getAuditStatus();
        if(!CourseConstants.AUDIT_DISPAST_STATUS.equals(auditStatus)&&!CourseConstants.AUDIT_UNPAST_STATUS.equals(auditStatus)){
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        //修改课程
        CourseBase courseBase1 = BeanHelper.copyProperties(dto, CourseBase.class);
        boolean b = this.updateById(courseBase1);
        if(!b){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //返回值
        Map map=new HashMap();
        map.put("courseBaseId",dto.getId());
        return ResponseResult.okResult(map);
    }

    //删除
    @Override
    public ResponseResult deleteCourseBase(Long courseId) {
        CourseBase courseBase = this.getById(courseId);
        if (ObjectUtils.isEmpty(courseBase)){
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //判断课程审核状态
        String auditStatus = courseBase.getAuditStatus();
        if (CourseConstants.AUDIT_PUBLISHED_STATUS.equals(auditStatus)||
                CourseConstants.AUDIT_PASTED_STATUS.equals(auditStatus)||
                CourseConstants.AUDIT_COMMIT_STATUS.equals(auditStatus)){
            throw new BusinessException(ErrorCode.DELETEERROR);//不可删除此课程
        }
        boolean b = this.removeById(courseBase);
        if (!b){
            throw new BusinessException(ErrorCode.ERROR);
        }

        //删除态，但是数据库里面保存数据
        courseBase.setStatus(CommonConstants.DELETE_FLAG);

        return ResponseResult.okResult(courseBase);
    }

    @Override//提交审核
    public ResponseResult commit(Long courseBaseId) {
        //根据id查询课程
        CourseBase courseBase = this.getById(courseBaseId);
        if (courseBase==null) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //设置课程的状态字段（已提交）
        courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        //更新
        boolean b = this.updateById(courseBase);
        if(!b){
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        return ResponseResult.okResult(null);
    }

    @Override
    public ResponseResult approve(CourseAuditDto dto) {
        //根据id查询课程
        CourseBase courseBase = this.getById(dto.getCourseBaseId());
        if (courseBase==null) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        //设置课程的状态字段(前端传递)
        courseBase.setAuditStatus(dto.getAuditStatus());
        //设置审核意见
        courseBase.setAuditMind(dto.getAuditMind());
        //更新
        boolean b = this.updateById(courseBase);
        if(!b){
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult(null);
    }
}
